#ifndef __CUHB_JMAT_CUH__
#define __CUHB_JMAT_CUH__

/*
  Copyright (c) 2010 Davide Rossetti (davide.rossetti@roma1.infn.it)

  This file is part of CuHB (CUDA Heisenberg) package.
  
  CuHB is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  CuHB is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  
  You should have received a copy of the GNU General Public License
  along with CuHB.  If not, see <http://www.gnu.org/licenses/>.

*/

/*
  the 3x3 Coupling matrix is split onto 2 float4 words

  - the float4 type should maximize the read bandwidth from the
    texture cache

  - the float3 type is not supported by texture cache

 */


//-----------------------------------------------------------------------------
// couplings
//-----------------------------------------------------------------------------

#include "jmat.hpp"

// compressed single J link
typedef struct __align__(16){
    float4 j0;
    float4 j1;
} jmatc;

// in units of???
static __constant__ int j_stride;

texture<float4, 1, cudaReadModeElementType> jTexSingle;

#define texJ jTexSingle

#if 1
// normal use
#define READ_J(tmp, texref, idx, dir)                                   \
    {                                                                   \
        float4 j0 = tex1Dfetch((texref), idx + ((dir*2+0)*j_stride));   \
        float4 j1 = tex1Dfetch((texref), idx + ((dir*2+1)*j_stride));   \
        tmp.j00 = j0.x; tmp.j01 = j0.y; tmp.j02 = j0.z;                 \
        tmp.j10 = j0.y; tmp.j11 = j1.x; tmp.j12 = j1.y;                 \
        tmp.j20 = j0.z; tmp.j21 = j1.y; tmp.j22 = j1.z;                 \
    }
#elif 0
// test mode 1: read 1 word
#warning "fake READ_J: reading twice"
#define READ_J(tmp, texref, idx, dir)                                   \
    {                                                                   \
        float4 j0 = tex1Dfetch((texref), idx + ((dir*2+0)*j_stride));   \
        float4 j1 = tex1Dfetch((texref), idx + ((dir*2+0)*j_stride));   \
        tmp.j00 = j0.x;                                                 \
        tmp.j01 = j0.y;                                                 \
        tmp.j02 = j0.z;                                                 \
        tmp.j11 = j1.x;                                                 \
        tmp.j12 = j1.y;                                                 \
        tmp.j22 = j1.z;                                                 \
        tmp.j10 = tmp.j01;                                              \
        tmp.j20 = tmp.j02;                                              \
        tmp.j21 = tmp.j12;                                              \
    }
#else
// test mode 2: read no words
#warning "fake READ_J: never read"
#define READ_J(tmp, texref, idx, dir)                                   \
    {                                                                   \
        float4 j0 = make_float4(0,0,0,0);                               \
        float4 j1 = make_float4(0,0,0,0);                               \
        tmp.j00 = j0.x;                                                 \
        tmp.j01 = j0.y;                                                 \
        tmp.j02 = j0.z;                                                 \
        tmp.j11 = j1.x;                                                 \
        tmp.j12 = j1.y;                                                 \
        tmp.j22 = j1.z;                                                 \
        tmp.j10 = tmp.j01;                                              \
        tmp.j20 = tmp.j02;                                              \
        tmp.j21 = tmp.j12;                                              \
    }
#endif

/*
 * Local variables:
 *  mode: c++
 *  c-indent-level: 4
 *  c-basic-offset: 4
 *  tab-width: 4
 *  indent-tabs-mode: nil
 * End:
 */

#endif // __CUHB_JMAT_CUH__
